package com.wkbb.basic.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.wkbb.basic.mapper.HolidaySystemMapper;
import com.wkbb.basic.mapper.OrgHolidayItemMapper;
import com.wkbb.basic.mapper.OrgHolidayMapper;
import com.wkbb.basic.mapper.OrganizationMapper;
import com.wkbb.basic.model.HolidaySystem;
import com.wkbb.basic.model.OrgHoliday;
import com.wkbb.basic.model.OrgHolidayItem;
import com.wkbb.basic.model.Organization;
import com.wkbb.basic.service.OrgHolidayService;
import com.wkbb.common.base.BaseServiceImpl;
import com.wkbb.common.dto.basic.OrgHolidayDto;
import com.wkbb.common.utils.HttpClientUtil;
import com.wkbb.common.utils.LocalDateUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;

/**
 * @author lizhichao
 * @date 2019/8/17
 * @description
 */
@Service
@Slf4j
public class OrgHolidayServiceImpl extends BaseServiceImpl implements OrgHolidayService {

    @Autowired
    private OrgHolidayMapper orgHolidayMapper;

    @Autowired
    private HolidaySystemMapper holidaySystemMapper;

    @Autowired
    private OrgHolidayItemMapper orgHolidayItemMapper;

    @Autowired
    private OrganizationMapper organizationMapper;

    @Autowired
    public void setMapper(OrgHolidayMapper mapper) {
        super.setMapper(mapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public PageInfo<OrgHolidayDto> getOrgHolidayPageInfoList(Map<String,Object> parms, Integer pageNo, Integer pageSize) throws Exception {

        if (pageNo == null || pageSize == null) {
            return null;
        }

        Map<String,Object> mapParms = new HashMap<>();
        mapParms.put("holidayYear",new SimpleDateFormat("yyyy").format(new Date()));

        //若当年系统节假日信息为空，则初始化
        if(CollectionUtils.isEmpty(holidaySystemMapper.getListByMapParams(mapParms))){
            this.initHolidaySystemInfo(mapParms);
        }

        //查询系统当年国家节假日信息并初始化设置表
        mapParms.put("orgId",parms.get("orgId"));
        if(CollectionUtils.isEmpty(orgHolidayMapper.getListByMapParams(mapParms))){
            List<OrgHoliday> orgHolidays = holidaySystemMapper.getHolidayInfoList(mapParms);
            if(orgHolidays!=null && !orgHolidays.isEmpty()){
                orgHolidayMapper.insertBatch(orgHolidays);
            }
        }

        //分页
        Page<OrgHolidayDto> page = PageHelper.startPage(pageNo, pageSize, true);
        PageInfo<OrgHolidayDto> pageInfo = new PageInfo(orgHolidayMapper.getHolidayInfoList(mapParms));
        pageInfo.setTotal(page.getTotal());

        if(!CollectionUtils.isEmpty(pageInfo.getList())){
            for(OrgHolidayDto orgHolidayDto : pageInfo.getList()){
                if(orgHolidayDto.getHolidayType() == 1 || orgHolidayDto.getHolidayType() == 2){
                    if(new SimpleDateFormat("yyyy-MM-dd").parse(orgHolidayDto.getStartHolidayDate()).compareTo(new Date())>0){
                        //设置为可编辑可删除
                        orgHolidayDto.setOperateType("0");
                    }else if(new SimpleDateFormat("yyyy-MM-dd").parse(orgHolidayDto.getStartHolidayDate()).compareTo(new Date())<0
                      && new SimpleDateFormat("yyyy-MM-dd").parse(orgHolidayDto.getEndHolidayDate()).compareTo(new Date())>0){
                        //设置为只能编辑
                        orgHolidayDto.setOperateType("2");
                    }else{
                        //设置为只读
                        orgHolidayDto.setOperateType("1");
                    }
                }else{
                    //设置为只读
                    orgHolidayDto.setOperateType("1");
                }
            }
        }

        return pageInfo;
    }

    @Override
    public List<OrgHoliday> getHolidayListByMapParams(Map<String,Object> parms) throws Exception{
        return orgHolidayMapper.getListByMapParams(parms);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addOrgHoliday(OrgHolidayDto orgHolidayDto) throws Exception {

        Date startHolidayDate = new SimpleDateFormat("yyyy-MM-dd").parse(orgHolidayDto.getStartHolidayDate());
        Date endHolidayDate = new SimpleDateFormat("yyyy-MM-dd").parse(orgHolidayDto.getEndHolidayDate());

        OrgHoliday orgHoliday = new OrgHoliday();
        orgHoliday.setHolidayName(orgHolidayDto.getHolidayName());
        orgHoliday.setHolidayType(orgHolidayDto.getHolidayType());
        orgHoliday.setOrgId(orgHolidayDto.getOrgId());
        orgHoliday.setStartHolidayDate(startHolidayDate);
        orgHoliday.setEndHolidayDate(endHolidayDate);
        orgHoliday.setHolidayYear(new SimpleDateFormat("yyyy").format(new Date()));
        orgHolidayMapper.insert(orgHoliday);
        //批量新增关联表
        List<OrgHolidayItem> orgHolidayItems = new ArrayList<>();
        for(Date d=startHolidayDate;d.compareTo(endHolidayDate)<=0;d=plusDay(1,d)){
            OrgHolidayItem holidayItem = new OrgHolidayItem();
            holidayItem.setHolidayId(orgHoliday.getId());
            holidayItem.setHolidayDate(d);
            holidayItem.setHolidayType(orgHoliday.getHolidayType());
            orgHolidayItems.add(holidayItem);
        }
        orgHolidayItemMapper.insertBatch(orgHolidayItems);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteByPrimaryKey(Long id) throws Exception{
        orgHolidayMapper.deleteByPrimaryKey(id);
        orgHolidayItemMapper.deleteByHolidayIdBatch(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateOrgHoliday(OrgHolidayDto orgHolidayDto) throws Exception {

        Date startHolidayDate = new SimpleDateFormat("yyyy-MM-dd").parse(orgHolidayDto.getStartHolidayDate());
        Date endHolidayDate = new SimpleDateFormat("yyyy-MM-dd").parse(orgHolidayDto.getEndHolidayDate());

        OrgHoliday orgHoliday = new OrgHoliday();
        orgHoliday.setId(orgHolidayDto.getId());
        orgHoliday.setHolidayName(orgHolidayDto.getHolidayName());
        orgHoliday.setHolidayType(orgHolidayDto.getHolidayType());
        orgHoliday.setOrgId(orgHolidayDto.getOrgId());
        orgHoliday.setStartHolidayDate(startHolidayDate);
        orgHoliday.setEndHolidayDate(endHolidayDate);
        orgHoliday.setHolidayYear(new SimpleDateFormat("yyyy").format(new Date()));

        orgHolidayMapper.updateByPrimaryKey(orgHoliday);
        //先删除关联表
        orgHolidayItemMapper.deleteByHolidayIdBatch(orgHoliday.getId());
        List<OrgHolidayItem> orgHolidayItems = new ArrayList<>();
        for(Date d=startHolidayDate;d.compareTo(endHolidayDate)<=0;d=plusDay(1,d)){
            OrgHolidayItem holidayItem = new OrgHolidayItem();
            holidayItem.setHolidayId(orgHoliday.getId());
            holidayItem.setHolidayDate(d);
            holidayItem.setHolidayType(orgHoliday.getHolidayType());
            orgHolidayItems.add(holidayItem);
        }
        //批量新增
        orgHolidayItemMapper.insertBatch(orgHolidayItems);

    }

    @Override
    public List<OrgHolidayItem> selectByMapParms(Map<String,Object> parms) throws Exception{

        Integer nextMonth = (Integer) parms.get("month") +1;
        String holidayDateStartStr =  new SimpleDateFormat("yyyy").format(new Date()) + "-" + parms.get("month") + "-01";
        String nextMonthStartStr = new SimpleDateFormat("yyyy").format(new Date()) + "-" + nextMonth + "-01";
        //时间转换
        Date holidayDateEnd =  plusDay(-1,new SimpleDateFormat("yyyy-MM-dd").parse(nextMonthStartStr));

        parms.put("holidayDateStart",holidayDateStartStr);
        parms.put("holidayDateEnd", new SimpleDateFormat("yyyy-MM-dd").format(holidayDateEnd));
        List<OrgHolidayItem> orgHolidayItems = holidaySystemMapper.selectByMapParms(parms);

        //删除和系统节假日表重复的记录
        for  ( int  i  =   0 ; i  <  orgHolidayItems.size()  -   1 ; i ++ )  {
            for  ( int  j  =  orgHolidayItems.size()  -   1 ; j  >  i; j -- )  {
                if  (orgHolidayItems.get(j).getHolidayDate().equals(orgHolidayItems.get(i).getHolidayDate()) &&
                        (orgHolidayItems.get(j).getHolidayType() == 3 || orgHolidayItems.get(j).getHolidayType() == 4))  {
                    orgHolidayItems.remove(j);
                }
            }
        }
        return orgHolidayItems;

    }


    @Override
    public List<OrgHolidayDto> getHolidayByYearMonth(Map<String,Object> parms) throws Exception{

        List<OrgHolidayDto> orgHolidayDtos = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String holidayDateStartStr = parms.get("yearMonth") + "-01";
        Date date = sdf.parse(holidayDateStartStr);
        LocalDate date1 = LocalDateUtil.date2LocalDate(date).plusMonths(1).minusDays(1);

        //时间转换
        parms.put("holidayDateStart",holidayDateStartStr);
        parms.put("holidayDateEnd", date1.toString());
        List<OrgHolidayItem> orgHolidayItems = holidaySystemMapper.selectByMapParms(parms);

        //删除和系统节假日表重复的记录
        for  ( int  i  =   0 ; i  <  orgHolidayItems.size()  -   1 ; i ++ )  {
            for  ( int  j  =  orgHolidayItems.size()  -   1 ; j  >  i; j -- )  {
                if  (orgHolidayItems.get(j).getHolidayDate().equals(orgHolidayItems.get(i).getHolidayDate()) &&
                        (orgHolidayItems.get(j).getHolidayType() == 3 || orgHolidayItems.get(j).getHolidayType() == 4))  {
                    orgHolidayItems.remove(j);
                }
            }
        }

        //调休日
        for(OrgHolidayItem orgHolidayItem : orgHolidayItems) {
            if (orgHolidayItem.getHolidayType() == 1 || orgHolidayItem.getHolidayType() == 3) {
                String dateTime = sdf.format(orgHolidayItem.getHolidayDate());
                parms.put("dateTime", dateTime);
                OrgHoliday orgHoliday = orgHolidayMapper.getOrgHolidayInfoByYearMonth(parms);
                if (orgHoliday != null) {
                    OrgHolidayDto orgHolidayDto = new OrgHolidayDto();
                    BeanUtils.copyProperties(orgHoliday, orgHolidayDto);
                    orgHolidayDto.setHolidayDate(dateTime);
                    orgHolidayDto.setStartHolidayDate(sdf.format(orgHoliday.getStartHolidayDate()));
                    orgHolidayDto.setEndHolidayDate(sdf.format(orgHoliday.getEndHolidayDate()));
                    orgHolidayDtos.add(orgHolidayDto);
                }
            }
        }
        return orgHolidayDtos;
    }

    /**
     * 初始化法定节假日和法定调休日
     * @throws Exception
     */
    private void initHolidaySystemInfo(Map<String,Object> mapParms) throws Exception {
        String url= "http://timor.tech/api/holiday/year/" + mapParms.get("holidayYear");
        List<HolidaySystem> holidaySystems = this.initHolidaySystem(url);
        holidaySystemMapper.insertBatch(holidaySystems);
    }

    /**
       * 指定日期加上天数后的日期
       * @param num 为增加的天数
       * @param newDate 创建时间
       * @return
       * @throws
       */
     private Date plusDay(int num,Date newDate) throws Exception{
         Calendar ca = Calendar.getInstance();
         ca.setTime(newDate);
         ca.add(Calendar.DATE, num);// num为增加的天数，可以改变的
         return ca.getTime();
     }

    /**
     * http请求获取当年节假日信息并初始化系统节假日信息表
     * @param url
     * @return
     */
    private List<HolidaySystem> initHolidaySystem(String url) throws Exception{

        List<HolidaySystem> holidaySystems = new ArrayList<>();
        //Object强转换为Map
        Map<String,Map> map = (Map)JSON.parse(HttpClientUtil.doGet(url));
        //将字符串转换成Map并组装系统节假日信息
        Map<String,Map> holidayMap = map.get("holiday");

        for(String key : holidayMap.keySet()){
            Map<String,Object> holidayDetail = holidayMap.get(key);
            HolidaySystem holidaySystem = new HolidaySystem();
            holidaySystem.setHolidayDate(new SimpleDateFormat("yyyy-MM-dd").parse(holidayDetail.get("date").toString()));
            holidaySystem.setHolidayName(holidayDetail.get("name").toString());
            if(holidayDetail.get("holiday").toString() == "false"){
                holidaySystem.setHolidayType((short)2);
            }else if(holidayDetail.get("holiday").toString() == "true"){
                holidaySystem.setHolidayType((short)1);
            }
            holidaySystem.setHolidayYear(new SimpleDateFormat("yyyy").format(new Date()));
            holidaySystems.add(holidaySystem);
        }
        return holidaySystems;
    }

    /**
     * 初始化节假日信息
     * */
    @Override
    public void initOrgHoliday(Long orgId)
    {

        try {
            List<Organization> orgList = new ArrayList();
            if(null==orgId)
            {
                List<Organization> organizationList = organizationMapper.getOrgListByType(new HashMap<>());
                if(!organizationList.isEmpty())
                {
                    orgList.addAll(organizationList);
                }
            }
            else
            {
                Organization organization = new Organization();
                organization.setId(orgId);
                orgList.add(organization);
            }

            Map<String, Object> mapParms = new HashMap<>();
            mapParms.put("holidayYear", new SimpleDateFormat("yyyy").format(new Date()));

            //若当年系统节假日信息为空，则初始化
            if (CollectionUtils.isEmpty(holidaySystemMapper.getListByMapParams(mapParms))) {
                this.initHolidaySystemInfo(mapParms);
            }

            //初始化学校节假日
            for(Organization organization : orgList) {
                //查询系统当年国家节假日信息并初始化设置表
                mapParms.put("orgId", organization.getId());
                List<OrgHoliday> orgHolidayList = orgHolidayMapper.getListByMapParams(mapParms);
                if (orgHolidayList.isEmpty()) {
                    List<OrgHoliday> orgHolidaySystemList = holidaySystemMapper.getHolidayInfoList(mapParms);
                    if (orgHolidaySystemList != null && !orgHolidaySystemList.isEmpty()) {
                        orgHolidayMapper.insertBatch(orgHolidaySystemList);
                    }
                }
            }
        }
        catch (Exception e)
        {
            log.error("初始化节假日信息异常",e.getMessage());
        }
    }
}
